/* verilator lint_off UNUSEDSIGNAL */
`include "defines.svh"
`default_nettype wire

module IF_STAGE(
    input clk,
    input reset,

    output logic if_valid,
    input logic id_ready,
    output if_to_id_bus_t if_to_id_bus,
    
    // forward
    input id_to_if_bypass_t id_to_if_bypass,
    input  exe_to_front_bypass_t exe_to_front_bypass,

    // sram
    output inst_sram_en,
    output word_t inst_sram_addr,
    input logic  axi_inst_flushreq
);

//pre-IF
word_t snpc,dnpc,if_pc;

assign snpc = if_pc + 32'h4;
assign dnpc = id_to_if_bypass.brjmp_en ? id_to_if_bypass.brjmp_pc : snpc ;


logic fd_shake,flush_if,stall_if;
assign flush_if = `OFF;
assign stall_if = exe_to_front_bypass.load_hazard_en | exe_to_front_bypass.store_hazard_en | axi_inst_flushreq;
assign fd_shake = if_valid & id_ready;

always_ff @(posedge clk) begin
    if(reset) begin
        if_valid <= `OFF;
    end else begin
        if_valid <= `ON;
    end
end

always_ff @(posedge clk) begin
    if(reset & ~if_valid) begin
        if_pc <= `BASE_ADDR;
    end else if(fd_shake & ~stall_if & ~flush_if) begin
        if_pc <= dnpc;
    end else if(flush_if & ~stall_if) begin
        if_pc <= `NULL;
    end
end

assign inst_sram_en = if_valid & ~id_to_if_bypass.brjmp_en & ~exe_to_front_bypass.load_hazard_en;
assign inst_sram_addr = if_pc;
assign if_to_id_bus.pc = if_pc;
assign if_to_id_bus.debug_dnpc = dnpc;


endmodule
